﻿package Common  
{
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.errors.IllegalOperationError;
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLStream;
	import flash.utils.ByteArray;
	import flash.utils.Endian;
	
	
	/**
	 * ...
	 * @author fox
	 */
	public class ActionManager 
	{
		
		
		////////////////////////////////////////////////////////////
		//data
		
		public var pal:Array = null;
		public var defaultData:Bitmap = null;
		
		public var loaderData:Object = null;
		public var acitonData:Object = null;
		
		public var bmpData:Object = null;
		
		public var lineArray:Array = null;
		
		public var stop:Boolean = false;
		public var isLoading:Boolean = false;
		
		
		
		public function ActionManager() 
		{
			
		}
		
		
		public static var instance:ActionManager = null;
		public static function Instance():ActionManager
		{
			if ( instance == null )
			{
				instance = new ActionManager();
			}
			
			return instance;
		}
		
		
		public function init( b:Bitmap , a:ByteArray ):void
		{
			lineArray = new Array();
			
			pal = new Array();
			
			defaultData = b;
			
			for ( var i:int = 0 ; i < 256 ; i++ )
			{
				var r1:int = a.readByte();
				var g1:int = a.readByte();
				var b1:int = a.readByte();
				var a1:int = 255;
				
				var c1:int = (a1 << 24) + (r1 << 16) + (g1 << 8) + ( b1 );
				pal[ i ] = c1;
			}
			
			pal[ 0 ] = 0;
			
			loaderData = new Object();
			acitonData = new Object();
			
			bmpData = new Object();
			bmpData[ GameDefine.INVALIDID ] = new Object();
			bmpData[ GameDefine.INVALIDID ].bd = b.bitmapData;
			bmpData[ GameDefine.INVALIDID ].px = -b.bitmapData.width * 0.5;
			bmpData[ GameDefine.INVALIDID ].py = -b.bitmapData.height;
			bmpData[ GameDefine.INVALIDID ].w = b.bitmapData.width;
			bmpData[ GameDefine.INVALIDID ].h = b.bitmapData.height;
		}
		
		
		public function relase():void
		{
			lineArray = null;
			
			loaderData = null;
			bmpData = null;
			acitonData = null;
			
			stop = false;
			isLoading = false;
		}
		
		
		public function stopLoading():void
		{
			stop = true;
		}
		
		
		public function startLoading():void
		{
			stop = false;
			
			if ( lineArray.length && !isLoading )
			{
				var id:int = lineArray[ 0 ];
				var loader:URLStream = loaderData[ id ].l;
				
				loader.load( new URLRequest( GameDefine.url + GameDefine.PATH + GameDefine.PATH1 + "action/" + id.toString() + ".act" ) );
			}
			else
			{
				
			}
		}
		
		
		public function clear():void
		{
			while( lineArray.length )
			{
				var id:int = lineArray[ 0 ];
				
				loaderData[ id ].l.removeEventListener( Event.COMPLETE , onStreamComplete );
				loaderData[ id ].l.removeEventListener( IOErrorEvent.IO_ERROR , onError );
				loaderData[ id ].l.removeEventListener( SecurityErrorEvent.SECURITY_ERROR , onSecurityError );
				
				
				loaderData[ id ].l = null;
				loaderData[ id ].f = null;
				loaderData[ id ] = null;
				delete loaderData[ id ];
				
				lineArray.shift();
			}
			
			stop = false;
			isLoading = false;
		}
		
		
		public function onStreamComplete( e:Event ):void
		{
			var ba:ByteArray = new ByteArray();
			ba.endian = Endian.LITTLE_ENDIAN;
			e.target.readBytes( ba , 0 , e.target.bytesAvailable );
			//ba.uncompress();
			
			var id:int = ba.readInt();
			var num:int = ba.readShort();
			var u:int = ba.readShort();
			
			acitonData[ id ] = new Object();
			acitonData[ id ].num = num;
			acitonData[ id ].u = u;
			acitonData[ id ].action = new Object();
			
			trace( "action " + id + " loaded" );
			
			for ( var i:int = 0 ; i < num ; i++ )
			{
				var direct:int = ba.readShort();
				var action:int = ba.readShort();
				var time:int = ba.readInt();
				var frame:int = ba.readInt();
				
				if ( !acitonData[ id ].action[ direct ] )
				{
					acitonData[ id ].action[ direct ] = new Object();
				}
				
				acitonData[ id ].action[ direct ][ action ] = new Object();
				acitonData[ id ].action[ direct ][ action ].time = time;
				acitonData[ id ].action[ direct ][ action ].frame = frame;
				acitonData[ id ].action[ direct ][ action ].action = new Array();
				
				for ( var j:int = 0 ; j < frame ; j++ )
				{
					var id1:int = ba.readInt();
					
					acitonData[ id ].action[ direct ][ action ].action.push( id1 );
				}
			}
			
			var imgNum:int = ba.readInt();
			
			
			acitonData[ id ].image = new Object();
			
			for ( i = 0 ; i < imgNum ; i++ )
			{
				var id2:int = ba.readInt();
				var px:int = ba.readInt();
				var py:int = ba.readInt();
				var w:int = ba.readInt();
				var h:int = ba.readInt();
				
				acitonData[ id ].image[ id2 ] = new Object();
				acitonData[ id ].image[ id2 ].px = px;
				acitonData[ id ].image[ id2 ].py = py;
				acitonData[ id ].image[ id2 ].w = w;
				acitonData[ id ].image[ id2 ].h = h;
				acitonData[ id ].image[ id2 ].data = new ByteArray();
				
				ba.readBytes( acitonData[ id ].image[ id2 ].data , 0 , w * h );
			}
			
			for ( i = 0 ; i < loaderData[ id ].f.length ; i++ )
			{
				loaderData[ id ].f[ i ]( acitonData[ id ] );
			}
			
			loaderData[ id ].l.removeEventListener( Event.COMPLETE , onStreamComplete );
			loaderData[ id ].l.removeEventListener( IOErrorEvent.IO_ERROR , onError );
			loaderData[ id ].l.removeEventListener( SecurityErrorEvent.SECURITY_ERROR , onSecurityError );
			
			loaderData[ id ].l = null;
			loaderData[ id ].f = null;
			loaderData[ id ] = null;
			delete loaderData[ id ];
			
			
			lineArray.shift();
			if ( lineArray.length && !stop )
			{
				id = lineArray[ 0 ];
				var loader:URLStream = loaderData[ id ].l;
				
				loader.load( new URLRequest( GameDefine.url + GameDefine.PATH + GameDefine.PATH1 + "action/" + id.toString() + ".act" ) );
			}
		}
		
		
		public function onError( event:IOErrorEvent ):void
		{
			lineArray.shift();
			if ( lineArray.length && !stop )
			{
				var id:int = lineArray[ 0 ];
				var loader:URLStream = loaderData[ id ].l;
				
				loader.load( new URLRequest( GameDefine.url + GameDefine.PATH + GameDefine.PATH1 + "action/" + id.toString() + ".act" ) );
			}
			
			trace( event );
			
			event.target.removeEventListener( Event.COMPLETE , onStreamComplete );
			event.target.removeEventListener( IOErrorEvent.IO_ERROR , onError );
			event.target.removeEventListener( SecurityErrorEvent.SECURITY_ERROR , onSecurityError );
		}
		
		
		public function onSecurityError( event:SecurityErrorEvent ):void
		{
			lineArray.shift();
			if ( lineArray.length && !stop )
			{
				var id:int = lineArray[ 0 ];
				var loader:URLStream = loaderData[ id ].l;
				
				loader.load( new URLRequest( GameDefine.url + GameDefine.PATH + GameDefine.PATH1 + "action/" + id.toString() + ".act" ) );
			}
			
			trace( event );
			
			event.target.removeEventListener( Event.COMPLETE , onStreamComplete );
			event.target.removeEventListener( IOErrorEvent.IO_ERROR , onError );
			event.target.removeEventListener( SecurityErrorEvent.SECURITY_ERROR , onSecurityError );
		}
		
		
		public function load( id:int , fun:Function ):void
		{
			
			if ( acitonData[ id ] )
			{
				fun( acitonData[ id ] );
				return;
			}
			
			if ( loaderData[ id ] )
			{
				loaderData[ id ].f.push( fun );
				return;
			}
			
			var loader:URLStream = new URLStream();
			loader.addEventListener( Event.COMPLETE , onStreamComplete );
			loader.addEventListener( IOErrorEvent.IO_ERROR , onError );
			loader.addEventListener( SecurityErrorEvent.SECURITY_ERROR , onSecurityError );
			
			loaderData[ id ] = new Object();
			loaderData[ id ].l = loader;
			loaderData[ id ].f = new Array();
			loaderData[ id ].f.push( fun );
			
			lineArray.push( id );
			
			if ( lineArray.length == 1 && !stop && !isLoading )
			{
				loader.load( new URLRequest( GameDefine.url + GameDefine.PATH + GameDefine.PATH1 + "action/" + id.toString() + ".act" ) );
			}
		}
		
		
		public function loadNPC( id:int , px:int , py:int ):void
		{
			if ( !loaderData[ id ] && !bmpData[ id ] )
			{
				var loader:Loader = new Loader();
				loader.name = id.toString();
				loader.contentLoaderInfo.addEventListener( Event.COMPLETE , onLoadTexture );
				loader.load( new URLRequest( GameDefine.PATH + GameDefine.PATH1 + "maptexture/" + id.toString() + ".png" ) );
				
				loaderData[ id ] = loader;
				
				bmpData[ id ] = new Object();
				bmpData[ id ].px = px;
				bmpData[ id ].py = py;
			}
			
		}
		
		
		public function onLoadTexture( event:Event ):void
		{
			var id:int = event.target.loader.name;
			
			bmpData[ id ].bd = event.target.loader.content.bitmapData;
			bmpData[ id ].w = bmpData[ id ].bd.width;
			bmpData[ id ].h = bmpData[ id ].bd.height;
			
			event.target.loader.contentLoaderInfo.removeEventListener( Event.COMPLETE , onLoadTexture );
			
			delete loaderData[ id ];
		}
		
		
		
	}
	
}


